#include "parseAbst.h"



#if defined(MAIN) && (MAIN)
#else
#define printf myprintf

int myprintf (__const char *__restrict __format, ...)
{
  return 0;
}
#endif


static char * generte_uuid()
{
  uuid_t uuid;
  uuid_generate(uuid);
  char *uuid_str = (char*)malloc(37);
  if(!uuid_str) return NULL;
  memset(uuid_str,0,37);
  uuid_unparse(uuid,uuid_str);
  uuid_clear(uuid);
  int i;
  for(i=0;i<36;i++){
    char *c = uuid_str + i;
    char *n = uuid_str + i + 1;
    if( *c != '-') continue;
    *c = 0;
    while(*n){
      char s = *c;
      *c = *n;
      *n = s;
      n++;
      c++;
    }
  }
  return uuid_str;
}

static u_char * tobase64(u_char *buf,int len)
{
  static char   basis64[] =
    		"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-";
  //char *res = (char*)malloc(len+1);
  //memset(res,0,len+1);
  int i = 0;
  for(;i<len;i++){
     char c = buf[i];
     //res[i] = basis64[c&0x3F]; 
     buf[i] = basis64[c&0x3F]; 
  }
  //printf("%s\n",buf);
  return buf;
}

size_t create_token(u_char **p)
{
  char     *str = generte_uuid();
  if(!str) return -1;
  u_char     *buf = (u_char*)malloc(7);
  if(!buf){
     free(str);
     return -1;
  }
  *p = buf;
  u_int8_t len  = strlen(str);
  int i,j=0,bi=0;
  for(i=0;i<len;i=i+2,j++){
    if(j%2 == 0){
      continue;
    }
    char *b = str + i; 
    char *e = str + i + 2; 
    char o  = *e;
    *e = 0;
    int ai = (int)strtoul(b,(char**)NULL,16);
    buf[bi++] = (char)ai;
    //printf("%s %d %d\n",b,ai,buf[bi-1]);
    *e = o;
    if(bi==6) break;
  }
  free(str); 
  tobase64(buf,6);
  //printf("%s\n",buf);
  return 6;
}

u_int64_t parse_token(u_char *str,size_t _len)
{
  int  i;
  u_int64_t ret = 0;
  u_int8_t  len = _len<=0?strlen((char*)str):_len;
  for(i=0;i<len;i++){
    u_char c = str[i];
    ret = (ret<<8) | c; 
    //printf("%c %d %llu\n",c,sizeof(u_int64_t),ret);
  } 
  return ret;
}



//util
static void  makeup_dir(char *path)
{
  if(!path || !strlen(path)) return;
  int ret = 0;
  char *p = strchr(path,'/');
  if(!p) return;
  char *l;
  while((l=strchr(++p,'/'))){
    *l = '\0';
    printf("makeup_dir():path:%s\n",path);
    ret = mkdir(path,S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH);
    *l = '/';
    p = l;
  }
}


static char *readbytes2uint(char *buff,u_int32_t *t,u_int8_t len)
{
  u_int8_t *p   = (u_int8_t*)buff;
  u_int8_t idx  = 0;
  u_int32_t res = 0;
  while(len>0){
    res = res | (((u_int32_t)(*(p+idx))) << ((len-1)*8)) ; 
    len--;
    idx++;
  }
  *t = res;
  return (char*)(p+idx);
}


static char * buff2uint(char *buff,u_int32_t *t)
{
  u_int8_t *p   = (u_int8_t*)buff;
  u_int32_t res = (((u_int32_t)(*p)) << 24)       | \
           	  (((u_int32_t)(*(p+1))) << 16)   | \
           	  (((u_int32_t)(*(p+2))) << 8 )   | \
           	  ((u_int32_t)(*(p+3)));
  *t = res;
  return (char*)(p+4);
}

static char *buff2ulong(char *buff,u_int64_t *t)
{
  u_int8_t *p = (u_int8_t *)buff;
  u_int64_t res =(((u_int64_t)(*p)) << 56)     |  \
                 (((u_int64_t)(*(p+1))) << 48) |  \
                 (((u_int64_t)(*(p+2))) << 40) |  \
                 (((u_int64_t)(*(p+3))) << 32) |  \
                 (((u_int64_t)(*(p+4))) << 24) |  \
                 (((u_int64_t)(*(p+5))) << 16) |  \
                 (((u_int64_t)(*(p+6))) << 8)  |  \
                 ((u_int64_t)(*(p+7)));
  *t = res;
  return (char*)(p+8); 
}

static char *uint2buff(char *buff,u_int32_t n)
{
  u_int8_t *p = (u_int8_t*)buff;
  *p++ = (n >> 24) & 0xFF;
  *p++ = (n >> 16) & 0xFF;
  *p++ = (n >> 8) & 0xFF;
  *p++ = n & 0xFF;
  return (char*)p; 
}

static char *uint642buff(char *buff,u_int64_t n)
{
  u_int8_t *p = (u_int8_t*)buff;
  *p++ = (n >> 56) & 0xFF;
  *p++ = (n >> 48) & 0xFF;
  *p++ = (n >> 40) & 0xFF;
  *p++ = (n >> 32) & 0xFF;
  *p++ = (n >> 24) & 0xFF;
  *p++ = (n >> 16) & 0xFF;
  *p++ = (n >> 8) & 0xFF;
  *p++ = n & 0xFF;
  return (char*)p; 
}

static char *uint82buff(char *buff,u_int8_t n)
{
  u_int8_t *p = (u_int8_t*)buff;
  *p++ = n & 0xFF;
  return (char*)p; 
}




static char* readstr(char *buff,int len,u_int8_t **res)
{ 
  int  idx = 0;
  char *p  = buff;
  *res = NULL; 

  if(!buff) return p; 
  if(len <= 0){
    while(*(buff+idx)){
       idx++;
    }
    len = idx; 
    idx = 0;
  }
  if(len <= 0) return p;
  u_int8_t *b = (u_int8_t*)malloc(len+1);
  if(!b) return p;
  memset(b,0,len+1);
  *res = b; 
  while((*p)){
    *b++ = *p++;
    idx++;
    if(idx >= len) break;
  } 
  return (char*)p;
}


static char* parseBoxInfo(char *buff,boxinfo_t *boxinfo)
{
  u_int32_t    v;
  u_int8_t     *s;
  char         *p    = buff2uint(buff,&v); 
  boxinfo->size = v;
  p = readstr(p,FIELD_TYPE_LENGTH,&s); 
  boxinfo->type = s;
  return p;
} 

static char * parseBox(char *buff,boxinfo_t *boxinfo,box_t *box)
{
   char *p = buff;
   u_int64_t size = boxinfo->size;
   u_int32_t boxLength = FIELD_SIZE_LENGTH + FIELD_TYPE_LENGTH;
   
   if (boxinfo->size == FLAG_USE_LARGE_SIZE)
   {
   	p = buff2ulong(buff,&size);
   	boxLength += FIELD_LARGE_SIZE_LENGTH;
   }

   /*if (strcmp(boxinfo->type,EXTENDED_TYPE) == 0)  //todo later
   {
   	// Read past the extended type.
   	//var extendedType:ByteArray = new ByteArray();
   	//readBytes(extendedType, 0, F4FConstants.FIELD_EXTENDED_TYPE_LENGTH);
   	
   	//boxLength += F4FConstants.FIELD_EXTENDED_TYPE_LENGTH;
   }*/
   
   box->size = size;
   box->type = boxinfo->type;
   box->boxLength = boxLength;
   return p;
}


static char * parseFullBox(char *buff,fullbox_t *fullbox)
{
  u_int32_t v;
  u_int32_t f;
  char *p = readbytes2uint(buff,&v,1); 
  p = readbytes2uint(p,&f,FULL_BOX_FIELD_FLAGS_LENGTH); 
  fullbox->version = v; 
  fullbox->flags = f; 
  return p;
}

static char * parsesegmentrunentry(char *buff,segmentrunentry_t *segrun)
{
  u_int32_t     v;
  char         *p = buff2uint(buff,&v);
  segrun->firstsegment = v;
  printf("segrun->firstsegment:%u\n",segrun->firstsegment);
  p = buff2uint(p,&v);
  segrun->fragspersegment = v;
  printf("segrun->segmentrunentry:%u\n",segrun->fragspersegment);
  return p;
}

static char * parseSegmentruntables(char *buff,segmentruntable_t *seg)
{
  /*
     u_int8_t              *type;
  u_int32_t             version:8;
  u_int32_t             flags:24;
  u_int32_t             qualityentrycount:8;
  u_int8_t              **qualitysegmentURLmodifiers;
  u_int32_t             segmentrunentrycount;
  segmentrunentry_t     *segmentrunentry;
  */

  u_int32_t     v;
  u_int8_t     *s;
  u_int8_t     i;
  char         *p = buff2uint(buff,&v);
  seg->size  = v; 
  printf("seg->size:%u\n",seg->size);
  p = readstr(p,FIELD_TYPE_LENGTH,&s);
  seg->type  = s; 
  printf("seg->type:%s\n",seg->type);
 
  p = readbytes2uint(p,&v,1); 
  seg->version  = v; 
  printf("seg->version:%u\n",seg->version);

  p = readbytes2uint(p,&v,3); 
  seg->flags  = v; 
  printf("seg->flags:%u\n",seg->flags);

  //for  qualityentrycount
  p = readbytes2uint(p,&v,1);
  seg->qualityentrycount  = v; 
  printf("seg->qualityentrycount:%u\n",seg->qualityentrycount);
  if(seg->qualityentrycount > 0){
    seg->qualitysegmentURLmodifiers = (u_int8_t**)malloc( (sizeof(u_int8_t*) * seg->qualityentrycount) );
    for(i=0;i<seg->qualityentrycount;i++){
      p = readstr(p,0,&s) + 1; //skip null 
      seg->qualitysegmentURLmodifiers[i] = s;
      printf("seg->qualitysegmentURLmodifiers[%u]:%s\n",i,seg->qualitysegmentURLmodifiers[i]);
    }
  }

  //for segmentrunentrycount
  p = buff2uint(p,&v);
  seg->segmentrunentrycount = v;
  printf("seg->segmentrunentrycount:%u\n",seg->segmentrunentrycount);
  if(seg->segmentrunentrycount > 0){
     seg->segmentrunentry = (segmentrunentry_t*)malloc( (sizeof(segmentrunentry_t)) * seg->segmentrunentrycount ); 
     for(i=0;i<seg->segmentrunentrycount;i++){
       p = parsesegmentrunentry(p,&seg->segmentrunentry[i]);
       printf("seg->segmentrunentry[%u]:%p",i,&seg->segmentrunentry[i]);
     }
  }

  return p;
}

static char * parsefragmentrunentry(char *buff,fragmentrunentry_t *fragrun)
{
  u_int32_t     v;
  u_int64_t     v64;
  char         *p = buff2uint(buff,&v);

  fragrun->firstfrag = v;
  printf("fragrun->firstfrag:%u\n",fragrun->firstfrag);

  p = buff2ulong(p,&v64);
  fragrun->firstfragtimestamp = v64;
  printf("fragrun->firstfragtimestamp:%lu\n",fragrun->firstfragtimestamp);

  p = buff2uint(p,&v);
  fragrun->fragduration = v;
  printf("fragrun->fragduration:%u\n",fragrun->fragduration);

  if( fragrun->fragduration == 0){
    p = readbytes2uint(p,&v,1);
    fragrun->discontinuityindicator = v;
    printf("fragrun->discontinuityindicator:%u\n",fragrun->discontinuityindicator);
  }

  return p;
}

static char * parseFragmenttruntables(char *buff,fragmentruntable_t *frag,abst_t *abst)
{
  u_int32_t     v;
  u_int8_t     *s;
  u_int32_t     i;
  char         *p = buff2uint(buff,&v);
  frag->size  = v; 
  printf("frag->size:%u\n",frag->size);
  p = readstr(p,FIELD_TYPE_LENGTH,&s);
  frag->type  = s; 
  printf("frag->type:%s\n",frag->type);
 
  p = readbytes2uint(p,&v,1); 
  frag->version  = v; 
  printf("frag->version:%u\n",frag->version);

  p = readbytes2uint(p,&v,3); 
  frag->flags  = v; 
  printf("frag->flags:%u\n",frag->flags);

  p = buff2uint(p,&v);
  frag->timescale = v;
  printf("frag->timescale:%u\n",frag->timescale);

  //for  qualityentrycount
  p = readbytes2uint(p,&v,1);
  frag->qualityentrycount = v;
  printf("frag->qualityentrycount:%u\n",frag->qualityentrycount);
  if(frag->qualityentrycount > 0){
    frag->qualitysegmentURLmodifiers = (u_int8_t**)malloc( (sizeof(u_int8_t*) * frag->qualityentrycount) );
    for(i=0;i<frag->qualityentrycount;i++){
      p = readstr(p,0,&s) + 1; //skip null 
      frag->qualitysegmentURLmodifiers[i] = s;
      printf("frag->qualitysegmentURLmodifiers[%u]:%s\n",i,frag->qualitysegmentURLmodifiers[i]);
    }
  }

  //for fragmentrunentrycount
  abst->fragmentrunentrycount_p = p;
  abst->fragmentrunentrycount_pos = p - abst->buff_b;
  p = buff2uint(p,&v);
  frag->fragmentrunentrycount = v;
  printf("frag->fragmentrunentrycount:%u\n",frag->fragmentrunentrycount);
  if(frag->fragmentrunentrycount > 0){
     frag->fragmentrunentry = (fragmentrunentry_t*)malloc( (sizeof(fragmentrunentry_t)) * frag->fragmentrunentrycount );
     for(i=0;i<frag->fragmentrunentrycount;i++){
       p = parsefragmentrunentry(p,&frag->fragmentrunentry[i]);
       if(i==(frag->fragmentrunentrycount-1))
         abst->lastfragidx = frag->fragmentrunentry[i].firstfrag;
       printf("frag->fragmentrunentry[%u]:%p lastfragidx:%d\n",i,&frag->fragmentrunentry[i],abst->lastfragidx);
       //if(p >= (abst->buff_b + abst->len)) return p; 
     }
  }


  return p;
}

int parseAbstByPath(char *path,abst_t *abst,FILE **fp)
{
   long len;
   if(!path) return -10;
   if((*fp=fopen(path,"r+")) == NULL){
      printf("fopen error:%s\n",strerror(errno));
      if(errno == ENOENT) return -2;
      return -11;
   }
   fseek(*fp,0L,SEEK_END);
   len = ftell(*fp); 
   void *buff = malloc(len);
   if(!buff){
     fclose(*fp);
     return -12;
   }
   memset(buff,0,len);
   fseek(*fp,0,SEEK_SET);

   int res = fread(buff,len,1,*fp);
   if(res == 0 && !feof(*fp)){
     errno = ferror(*fp);
     printf("fread error:%s\n",strerror(errno));
     fclose(*fp);
     free(buff);
     return -13;
   }
  
   abst->buff_b = (char*)buff;
   abst->len    = len;
   parseAbst(buff,abst);
   free(buff);
   return 0;
}

char *parseAbst(char *buff,abst_t *abst)
{
  boxinfo_t boxinfo;
  u_int32_t v;
  u_int64_t v64;
  u_int8_t  *s;
  u_int8_t  i;
  char *p = buff;

  p = parseBoxInfo(p,&boxinfo);
  printf("boxinfo.size:%d boxinfo.type:%s %p\n",boxinfo.size,boxinfo.type,boxinfo.type);
  p = parseBox(p,&boxinfo,&abst->fullbox.box);
  //printf("box.size:%ld box.type:%s  box.boxLength:%d\n",(long)box.size,box.type,box.boxLength);
  p = parseFullBox(p,&abst->fullbox);
  printf("fullbox.version:%d fullbox.flags:%d\n",abst->fullbox.version,abst->fullbox.flags);

  //for bootstrapVersion 
  p = buff2uint(p,&v); 
  abst->bootstrapVersion = v;
  printf("bootstrapVersion:%d\n",abst->bootstrapVersion);
  //for profile live update 
  p = readbytes2uint(p,&v,1); 
  abst->profile = (v >> 6);
  abst->live = ((v & 0x20) == 0x20);
  abst->update = ((v & 0x1) == 0x1);
  printf("v:%d profile:%d live:%d update:%d\n",v,abst->profile,abst->live,abst->update);
  //for timescale 
  p = buff2uint(p,&v); 
  abst->timescale = v;
  printf("timescale:%u\n",abst->timescale);
  //for currentMediaTime
  p = buff2ulong(p,&v64); 
  abst->currentmediatime = v64;
  printf("currentMediaTime:%lu\n",abst->currentmediatime);

  //for smptetimecodeoffset
  p = buff2ulong(p,&v64); 
  abst->smptetimecodeoffset = v64;
  printf("smptetimecodeoffset:%lu\n",abst->smptetimecodeoffset);

  //for movieidentifier
  p = readstr(p,0,&s) + 1; //skip null 
  abst->movieidentifier = s;
  printf("movieidentifier:%s\n",abst->movieidentifier);
  //for  serverentrycount
  p = readbytes2uint(p,&v,1);
  abst->serverentrycount = v;
  printf("serverentrycount:%u\n",abst->serverentrycount);
  if(abst->serverentrycount > 0){
    abst->serverbaseURLs = (u_int8_t**)malloc( (sizeof(u_int8_t*) * abst->serverentrycount) );
    for(i=0;i<abst->serverentrycount;i++){
      p = readstr(p,0,&s) + 1; //skip null 
      abst->serverbaseURLs[i] = s;
      printf("abst->serverbaseURLs[%u]:%s\n",i,abst->serverbaseURLs[i]);
    }
  }

  //for  qualityentrycount
  p = readbytes2uint(p,&v,1);
  abst->qualityentrycount = v;
  printf("qualityentrycount:%u\n",abst->qualityentrycount);
  if(abst->qualityentrycount > 0){
    abst->qualitysegmentURLmodifiers = (u_int8_t**)malloc( (sizeof(u_int8_t*) * abst->qualityentrycount) );
    for(i=0;i<abst->qualityentrycount;i++){
      p = readstr(p,0,&s) + 1; //skip null 
      abst->qualitysegmentURLmodifiers[i] = s;
      printf("abst->qualitysegmentURLmodifiers[%u]:%s\n",i,abst->qualitysegmentURLmodifiers[i]);
    }
  }


  //for drmdata 
  p = readstr(p,0,&s) + 1; //skip null 
  abst->drmdata = s;

  //for metadata
  p = readstr(p,0,&s) + 1; //skip null 
  abst->metadata = s;
  printf("abst->drmdata:%s abst->metadata:%s\n",abst->drmdata,abst->metadata);

  //for segmentcount
  p = readbytes2uint(p,&v,1);
  abst->segmentcount = v;
  printf("segmentcount:%u\n",abst->segmentcount);
  if(abst->segmentcount > 0){
    abst->segmentruntables = (segmentruntable_t*)malloc( (sizeof(segmentruntable_t) * abst->segmentcount) );
    for(i=0;i<abst->segmentcount;i++){
      p = parseSegmentruntables(p,&abst->segmentruntables[i]);
      printf("abst->segmentruntables[%u]:%p\n",i,&abst->segmentruntables[i]);
    }
  }

  //for fragmentcount
  p = readbytes2uint(p,&v,1);
  abst->fragmentcount = v;
  printf("fragmentcount:%u\n",abst->fragmentcount);
  if(abst->fragmentcount > 0){
    abst->fragmentruntables = (fragmentruntable_t*)malloc( (sizeof(fragmentruntable_t) * abst->fragmentcount) );
    for(i=0;i<abst->fragmentcount;i++){
      p = parseFragmenttruntables(p,&abst->fragmentruntables[i],abst);
      printf("abst->fragmentruntables[%u]:%p\n",i,&abst->fragmentruntables[i]);
    }
  }

  return p;
}

void destoryAbst(abst_t *abst)
{
  u_int8_t  i;
  if(!abst) return;

  if(abst->fullbox.box.type){
    free(abst->fullbox.box.type);
    abst->fullbox.box.type = NULL;
  }
  
  if(abst->movieidentifier){
    free(abst->movieidentifier);
    abst->movieidentifier = NULL;
  }

  if(abst->serverentrycount > 0 && abst->serverbaseURLs){
    for(i=0;i<abst->serverentrycount;i++){
      free(abst->serverbaseURLs[i]);
    } 
    free(abst->serverbaseURLs);
    abst->serverbaseURLs = NULL;
  }

  if(abst->qualityentrycount > 0 && abst->qualitysegmentURLmodifiers){
    for(i=0;i<abst->serverentrycount;i++){
      free(abst->qualitysegmentURLmodifiers[i]);
    } 
    free(abst->qualitysegmentURLmodifiers);
    abst->qualitysegmentURLmodifiers = NULL;
  }

  if(abst->drmdata){
    free(abst->drmdata);
    abst->drmdata = NULL;
  }

  if(abst->metadata){
    free(abst->metadata);
    abst->metadata = NULL;
  }

  if(abst->segmentcount >0 && abst->segmentruntables){
    for(i=0;i<abst->segmentcount;i++){
      segmentruntable_t *r = &abst->segmentruntables[i];

      if(r->type){
        free(r->type);
        r->type = NULL;
      } 

      if(r->qualityentrycount > 0 && r->qualitysegmentURLmodifiers){
        for(i=0;i<r->qualityentrycount;i++){
          free(r->qualitysegmentURLmodifiers[i]);
        } 
        free(r->qualitysegmentURLmodifiers);
        r->qualitysegmentURLmodifiers = NULL;
      }
    
      if(r->segmentrunentrycount > 0 && r->segmentrunentry){
        free(r->segmentrunentry);
        r->segmentrunentry = NULL;
      }
    } 
    free(abst->segmentruntables);
    abst->segmentruntables = NULL;
  }

  if(abst->fragmentcount >0 && abst->fragmentruntables){
    for(i=0;i<abst->fragmentcount;i++){
      fragmentruntable_t *r = &abst->fragmentruntables[i];

      if(r->type){
        free(r->type);
        r->type = NULL;
      } 

      if(r->qualityentrycount > 0 && r->qualitysegmentURLmodifiers){
        for(i=0;i<r->qualityentrycount;i++){
          free(r->qualitysegmentURLmodifiers[i]);
        } 
        free(r->qualitysegmentURLmodifiers);
        r->qualitysegmentURLmodifiers = NULL;
      }
    
      if(r->fragmentrunentrycount > 0 && r->fragmentrunentry){
        free(r->fragmentrunentry);
        r->fragmentrunentry = NULL;
      }
    } 
    free(abst->fragmentruntables);
    abst->fragmentruntables = NULL;
  }
}


int create_abst_file(char *path,char *buff,size_t len)
{
   FILE *fp = NULL;
   if(!path) return -10;
   if((fp=fopen(path,"r+")) == NULL){
      printf("fopen error:%s\n",strerror(errno));
      if(errno == ENOENT){
        makeup_dir(path); 
        if((fp=fopen(path,"a+")) == NULL)
          return -11;
      }else{
        return -12;
      }
   }
  
   int ret = fwrite(buff,len,1,fp);
   if(ret == 0 && ferror(fp)){
      fclose(fp);
      return -13;
   }
   fclose(fp);
   return 0; 
}

void repeat_fragmentrunentrycount(FILE *fp,size_t pos,u_int32_t cnt)
{
   fseek(fp,pos,SEEK_SET);
   char buff[4] = {'\0'}; 
   uint2buff(buff,cnt);
   fwrite(buff,4,1,fp);
}

void append_fragmentrunentry(FILE *fp,fragmentrunentry_t *entry)
{
   fseek(fp,0L,SEEK_END);
   char buff[17] = {'\0'};
   /*char firstFragment_buff[4] = {'\0'}; 
   char firstFragmentTimestamp_buff[8] = {'\0'}; 
   char fragmentDuration_buff[4] = {'\0'}; 
   char discontinuityIndicator_buff[1] = {'\0'}; */
   
   uint2buff(buff,entry->firstfrag);
   uint642buff(buff+4,entry->firstfragtimestamp);
   uint2buff(buff+12,entry->fragduration);
   if(entry->fragduration == 0)
     uint82buff(buff+16,entry->discontinuityindicator);
   fwrite(buff,entry->fragduration?16:17,1,fp);
}

#if defined(MAIN) && (MAIN)
int main(int argc , char *argv[])
{
   abst_t    abst;
   //long      len;
   memset(&abst,0,sizeof(abst_t));
   FILE *fp;
   //char *p  = NULL;

   int ret = parseAbstByPath(argv[1],&abst,&fp);
   printf("ret:%d  %p\n",ret,fp);

   if(abst.fragmentcount > 0 && abst.fragmentruntables){
    u_int8_t i;
    for(i=0;i<abst.fragmentcount;i++){
      fragmentruntable_t *r = &abst.fragmentruntables[i];
      if(r->fragmentrunentrycount > 0 && r->fragmentrunentry){
         printf("cnt:%u\n",r->fragmentrunentrycount);
         u_int32_t j;
         for(j=0;j<r->fragmentrunentrycount;j++){
            fragmentrunentry_t *re = &r->fragmentrunentry[j];
            printf("seg:%u\n",re->firstfrag);
         }
      }
    } 
   }

   
   ///repeat_fragmentrunentrycount(fp,abst.fragmentrunentrycount_pos,300);
   fclose(fp);

   /*printf("fopen  filename:%s\n",argv[1]);
   if((fp=fopen(argv[1],"r+")) == NULL){
      printf("fopen error:%s\n",strerror(errno));
      exit(-1);
   }
   fseek(fp,0L,SEEK_END);
   len = ftell(fp); 
   void *buff = malloc(len);
   memset(buff,0,len);
   fseek(fp,0,SEEK_SET);

   int res = fread(buff,len,1,fp);
   if(res < 0){
      printf("fread error:%s\n",strerror(errno));
      fclose(fp);
      exit(-1);
   }
   if(res == 0 && !feof(fp)){
     errno = ferror(fp);
     printf("fread error:%s\n",strerror(errno));
     fclose(fp);
     exit(-1);
   }

   abst.buff_b = buff;
   abst.len    = len;
   p = parseAbst(buff,&abst);

   if(abst.fragmentcount > 0 && abst.fragmentruntables){
    u_int8_t i;
    for(i=0;i<abst.fragmentcount;i++){
      fragmentruntable_t *r = &abst.fragmentruntables[i];
      if(r->fragmentrunentrycount > 0 && r->fragmentrunentry){
         u_int8_t j;
         for(j=0;j<r->fragmentrunentrycount;j++){
            fragmentrunentry_t *re = &r->fragmentrunentry[j];
            printf("seg:%u\n",re->firstfrag);
         }
      }
    } 
   }

   char *fragmentrunentrycount_p = abst.fragmentrunentrycount_p;
   

   len = len - (fragmentrunentrycount_p+4-(char*)buff); 
   if(abst.fragmentcount > 0){
     repeat_fragmentrunentrycount(fp,(fragmentrunentrycount_p-(char*)buff),10);
     fseek(fp,0L,SEEK_END);
     size_t n = fwrite(fragmentrunentrycount_p+4,len,1,fp);
     printf("has writen %d\n",n);
   }

   destoryAbst(&abst);

   free(buff);
   fclose(fp);*/
   return 0;
}
#endif
